/* 
 * File:   Rref.h
 * Author: gustavo
 *
 * Created on August 19, 2012, 12:53 AM
 */

#ifndef RREF_H
#define	RREF_H

#include "RrefInterface.h"

namespace imp {

	namespace math {

		template <typename T, class Algorithm > class Rref : public RrefInterface<T> {
			/////
		protected:
			Matrix<T> R; // reduced form
			Matrix<T> N; // null space
			Matrix<char> Ind;
			int rank;

		public: /* Constructors */
			Rref(Matrix<T>& orig);
			virtual ~Rref();

		public: /* Implements RrefInterface */
			const Matrix<T>& getReducedForm() const;
			const Matrix<T>& getNullSpace() const;
			bool hasNullSpace() const;
			int getRank() const;

		public: /* Implements TransformInterface */
			void transform(Matrix<T>& M);
			bool modifiedInput() const;

		private:

		};

		/* = Constructors ======================================================= */
		template <typename T, class Algorithm > Rref<T, Algorithm>::Rref(Matrix<T>& orig) {

			this->Ind.setSize(1, orig.columns);
			this->transform(orig);

		}

		template <typename T, class Algorithm > Rref<T, Algorithm>::~Rref() {
		}

		/* = Implements RrefInterface =========================================== */
		template <typename T, class Algorithm > const Matrix<T>& Rref<T, Algorithm>::getReducedForm() const {
			return this->R;
		}

		template <typename T, class Algorithm > const Matrix<T>& Rref<T, Algorithm>::getNullSpace() const {
			return this->N;
		}

		template <typename T, class Algorithm > bool Rref<T, Algorithm>::hasNullSpace() const {
			return N.size > 0;
		}

		template <typename T, class Algorithm > int Rref<T, Algorithm>::getRank() const {
			return this->rank;
		}

		/* = Implements TransforInterface ======================================= */

		/*
		 * Each algorithm implements its methods!
		 */
	}

}
#endif	/* RREF_H */

